package com.example.demo.Controller;

import com.example.demo.dao.ResourceRepository;
import com.example.demo.dao.UserRepository;
import com.example.demo.domain.Resource;
import com.example.demo.domain.User;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class FileUp {
    /*
    *  FileUp  的默认RequestMapping("/")
    *
    * url;
    *       /     # 默然
    *       /parameter/{username}   # 带PathVariable参数请求
    *       /post  # post 请求
    *       /CreateDir/{filename}/{id} 创建文件
    *
    * */

    @Autowired
    private ResourceRepository resourceRepository;

    @Autowired
    private UserRepository userRepository;


    //private String rootdir = ResourceUtils.getURL("classpath:").getPath()+"../";

    private String rootdir = "";

    public FileUp() throws FileNotFoundException {

    }

    //PathVariable demo
    @RequestMapping(path = "/parameter/{username}")
    @ResponseBody
    public String param(@PathVariable("username") String username){
        return String.format("%s",username);
    }


    @RequestMapping(path = "/upuser/{username}/{filename}/{ip}")
    @ResponseBody
    public String upuser(@PathVariable("username") String username,@PathVariable("filename") String filename,@PathVariable("ip") String ip){
        return String.format("%s",username);
    }

    @RequestMapping(value = "/post",method = RequestMethod.POST )
    @ResponseBody
    public String post(){
        return "post";
    }
    /*
    * 创建目录
    * */
    @RequestMapping(value = "/CreateDir/{filename}/{id}",method = RequestMethod.GET )
    @ResponseBody
    public String CreateDir(@PathVariable("filename") String filename,@PathVariable("id") long id){
        StringBuilder sb = new StringBuilder();
        Resource parent = resourceRepository.findById(id);
        while (parent.getParent()!=null){
            sb.insert(0,parent.getName()+"/");
            parent = parent.getParent();
        }
        sb.insert(0,parent.getName()+"/");
        sb.insert(0,rootdir+"file/");
        String dir = sb.toString();
        File newdir = new File(dir);
        System.out.println("CreateDir:"+dir);
        if(!newdir.exists()){
            if(newdir.mkdirs())
            {
                return "success";
            }
        }
        return "error";
    }
    /*
    * 删除文件以及子文件
    * */
    @RequestMapping(value = "/DeleteDir/{id}",method = RequestMethod.GET)
    @ResponseBody
    public String DeleteDir(@PathVariable("id") long id){
        StringBuilder sb = new StringBuilder();
        Resource resource = resourceRepository.findById(id);
        String initname = resource.getName();

        List<Resource> childs = resourceRepository.findChildsByParent(resource);
        sb.append(initname);
        while(resource.getParent()!=null){
            resource = resource.getParent();
            sb.insert(0,resource.getName()+"/");
        }
        sb.insert(0,rootdir+"file/");

        System.out.println(sb.toString());
        File deletefile = new File(sb.toString());

        if(!deletefile.exists()){
            System.out.println("删除文件不存在");
            return "success";
        }

        if(deletefile.isFile()){
            if(!deleteFile(deletefile)){
                System.out.println("删除"+ deletefile +"失败");
                return "error";
            }
        }else{
            if(!deleteDirectory(deletefile)){
                System.out.println("删除"+ deletefile +"失败");
                return "error";
            }
        }
        System.out.println(deletefile+"删除成功");
        return "success";
    }

    /*
    * 根据id获取User
    * */
    @RequestMapping(value = "/u/{id}",method = RequestMethod.GET)
    @ResponseBody
    public HashMap<String,String> GetUserByID(@PathVariable("id") long id){
        List<User> result = userRepository.findById(id);
        return result.get(0).ToArray();
    }


    /*
    * 根据id 找到Resource
    * */
    @RequestMapping(value = "/r/{id}",method = RequestMethod.GET )
    @ResponseBody
    public HashMap<String, String> GetResourceById(@PathVariable("id") long id){
       Resource result = resourceRepository.findById(id);
       return result.ToArray();
    }

    /*
    * 根据name 模糊查找Resource
    * */
    @RequestMapping(value = "/resource/like/{name}",method = RequestMethod.GET )
    @ResponseBody
    public List<Resource> GetResourceLikeName(@PathVariable("name") String name){
        List<Resource> result = resourceRepository.findByNameLike("%"+name+"%");
        for(Resource r : result){
            System.out.println(r.getName());
        }
        return null;
    }


    /*上传
    * */
    @RequestMapping("/fileup/{rid}")
    @ResponseBody
    public String fileup(@RequestParam("file") MultipartFile file,@PathVariable("rid") long rid){
        System.out.println(rid);
        if(!file.isEmpty()){
            try{
                Resource parent = resourceRepository.findById(rid);
                StringBuilder sb = new StringBuilder();
                sb.insert(0,parent.getName()+"/");
                while(parent.getParent() != null){
                    parent = parent.getParent();
                    sb.insert(0,parent.getName()+"/");
                }
                sb.insert(0,rootdir+"file/");
                System.out.println(sb.toString());
                //文件路径
                BufferedOutputStream out = new BufferedOutputStream(
                        new FileOutputStream(new File(sb.toString()+
                                file.getOriginalFilename())));
                out.write(file.getBytes());
                out.flush();
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return "error";
            } catch (IOException e) {
                e.printStackTrace();
                return "error";
            }
            return "success";
        }
        else {
            return "error";
        }
    }
    /*
    * 测试用
    * */
//    @RequestMapping(value = "/dir", method = RequestMethod.GET)
//    @ResponseBody
//    public String dir() throws FileNotFoundException {
//        return ResourceUtils.getURL("classpath:").getPath();
//    }

//    @RequestMapping(value = "/upfile", method = RequestMethod.POST)
//    @ResponseBody
//    public String handleFileUpload(HttpServletRequest request) {
//        MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);
//        List<MultipartFile> files = ((MultipartHttpServletRequest) request)
//                .getFiles("file");
//        String name=params.getParameter("name");
//        System.out.println("name:"+name);
//        String id=params.getParameter("id");
//        System.out.println("id:"+id);
//        MultipartFile file = null;
//        BufferedOutputStream stream = null;
//        for (int i = 0; i < files.size(); ++i) {
//            file = files.get(i);
//            if (!file.isEmpty()) {
//                try {
//                    byte[] bytes = file.getBytes();
//                    stream = new BufferedOutputStream(new FileOutputStream(
//                            new File(file.getOriginalFilename())));
//                    stream.write(bytes);
//                    stream.close();
//                } catch (Exception e) {
//                    stream = null;
//                    return "You failed to upload " + i + " => "
//                            + e.getMessage();
//                }
//            } else {
//                return "You failed to upload " + i
//                        + " because the file was empty.";
//            }
//        }
//        return "upload successful";
//    }
    /*
    * 更名
    * */
    @RequestMapping(value = "AlterFileName/{id}/{newname}/{oldname}",method = RequestMethod.GET)
    public String AlterFileName(@PathVariable("id") long id,@PathVariable("newname") String newname,@PathVariable("oldname") String oldname) throws IOException {
        String Path = GetParentPath(id) + oldname;
        System.out.println(Path);
        File oldfile = new File(Path);
        if(!oldfile.exists()){
            oldfile.createNewFile();
        }
        File newfile = new File(oldfile.getParent()+File.separator+newname);
        if(oldfile.renameTo(newfile)){
            System.out.println("更名完成");
            return "success";
        }else{
            return "error";
        }

    }







    ///下载
    @RequestMapping(path = "/downfile/{id}",method = RequestMethod.POST)
    public ResponseEntity<FileSystemResource> experimented(@PathVariable("id") long id) throws UnsupportedEncodingException {
        Resource parent = resourceRepository.findById(id);
        StringBuilder sb = new StringBuilder();
        sb.insert(0,parent.getName());
        while(parent.getParent() != null){
            parent = parent.getParent();
            sb.insert(0,parent.getName()+"/");
        }
        sb.insert(0,rootdir+"file/");
        System.out.println("下载完成："+sb.toString());
        return exportfile(new File(sb.toString()));
    }
    /*
    * 下载
    * */
    private ResponseEntity<FileSystemResource> exportfile(File file) throws UnsupportedEncodingException {
        if (file == null) {
            return null;
        }
        //new String(file.getName().getBytes("ISO-8859-1"), "UTF-8")
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept-Charset","utf-8");
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new FileSystemResource(file));
    }


    /*
    *  上面使用的函数工具
    * */

    /*
    * 1 删除文件
    * @param 文件类
    * @return 删除成功返回true，否则返回false
    * */
    public boolean deleteFile(File file) {
        boolean flag = false;
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 2 删除目录以及目录下的文件
     * @param   dirFile 被删除目录文件类
     * @return  目录删除成功返回true，否则返回false
     */
    public boolean deleteDirectory(File dirFile) {
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(new File(files[i].getAbsolutePath()));
                if (!flag) break;
            } //删除子目录
            else {
                flag = deleteDirectory(new File(files[i].getAbsolutePath()));
                if (!flag) break;
            }
        }
        if (!flag) return false;
        //删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }
    /*
    * 3 获取资源路径
    * @param Resource 的id
    * @return 返回路径
    * */
    private String GetParentPath(long id){
        Resource parent = resourceRepository.findById(id);
        StringBuilder sb = new StringBuilder();
        while (parent.getParent()!=null){
            parent = parent.getParent();
            sb.insert(0,parent.getName()+"/");
        }
        sb.insert(0,rootdir+"file/");

        return sb.toString();
    }

}
